'use strict';

var lgTable = angular.module('lgTable', ['ngTable', 'lgUtils']);

lgTable.controller('TableCtrl', ['NgTableParams','List', 'TableParams', 'resource', 
function(NgTableParams, List, TableParams, resource){

    var self = this;

    self.cols = TableParams.columns();

	self.isAdding = false;

	var settings = TableParams.settings();

	var Resource = resource();	

	settings.getData = Resource.query;

    self.tableParams = new NgTableParams(TableParams.params(), settings);

    var originalData = [];


    function cancel(row, rowForm){

        if(row.isAdding){
            var rows = self.tableParams.data;
            List.remove(rows, function(r){
                return r.id === row.id;
            });

        } else {

            var originalRow = retrieveRow(row);
            angular.extend(row, originalRow);
            List.remove(originalData, function(item){
                return row.id === item.id;
            });
        }

        resetRow(row, rowForm);

    }

    function del(row){

		row.$remove();
        List.remove(self.tableParams.data, function(item){
            return row === item;
        });

        console.info('row',row);        
        resource.delete({id:row.image});
        /*
           self.tableParams.reload().then(function(data){
           if(data.length === 0 && self.tableParams.total()>0){
           self.tableParams.page(self.tableParams.page() - 1);
           self.tableParams.reload();
           }
           });
           */
    }

    function retrieveRow(row){
        return List.findOne(originalData, function(r){
            return r.id === row.id;
        });
    }

    function resetRow(row, rowForm){
		if(row.isAdding){
			self.isAdding = false;
			delete row.isAdding;
		}
		if(row.isEditing){
			delete row.isEditing;
		}
        rowForm.$setPristine();
        self.tableTracker.untrack(row);
    }

    function save(row, rowForm){

        resetRow(row, rowForm);
		row.$save();
        List.remove(originalData, function(item){
            return row.id === item.id;
        });

    }

    function edit(row){
        originalData.push(angular.copy(row));
        row.isEditing = true;
    }

    function add(){
		if(! self.isAdding){
			var rows = self.tableParams.data;
			var row = new Resource();
			row.isEditing = true;
			row.isAdding = true;
			rows.unshift(row);
		
			self.isAdding = true;
		}
    }

    self.cancel = cancel;
    self.del = del;
    self.save = save;
    self.edit = edit;
    self.add = add;

}]);

lgTable.directive('trackTable',['List', function(List){

    return {
        restrict:'A',
        priority:-1,
        require:'ngForm',
        controller: function($scope, $parse, $attrs, $element){
            var self = this;
            self.tableForm = $element.controller('form');
            var dirtyCellsByRow = [];
            var invalidCellsByRow = [];

            function init(){
                var setter = $parse($attrs.trackTable).assign;
                setter($scope, self);
                $scope.$on('$destroy', function(){
                    setter(null);
                });
            }

            init();


            function setInvalid(isInvalid){
                self.$invalid = isInvalid;
                self.$valid = !isInvalid;
            }

            function getCellsForRow(row, cellsByRow){
                return List.findOne(cellsByRow, function(entry){
                    return entry.row.id === row.id;
                });
            }

            function setCellStatus(row, cell, value, cellsByRow){

                var rowCells = getCellsForRow(row, cellsByRow);
                if(!rowCells && !value){
                    return;
                }

                if(value){
                    if(!rowCells){
                        rowCells = {
                            row:row,
                            cells:[]
                        };
                        cellsByRow.push(rowCells);
                    } 

                    if(rowCells.cells.indexOf(cell) === -1){
                        rowCells.cells.push(cell);
                    }

                } else {
                    List.remove(rowCells.cells, function(item){
                        return cell === item;
                    });

                    if(rowCells.cells.length===0){
                        List.remove(cellsByRow, function(item){
                            return rowCells === item;
                        });
                    }
                }

            }

            self.reset = function(){
                dirtyCellsByRow = [];
                invalidCellsByRow = [];
                setInvalid(false);
            };

            self.isCellDirty = function(row, cell){
                var rowCells = getCellsForRow(row, dirtyCellsByRow);
                return rowCells && rowCells.cells.indexOf(cell) !== -1;
            };

            self.setCellDirty = function(row, cell, isDirty){
                setCellStatus(row, cell, isDirty, dirtyCellsByRow);
            };

            self.setCellInvalid=function(row, cell, isInvalid){

                setCellStatus(row, cell, isInvalid, invalidCellsByRow);
                setInvalid(invalidCellsByRow.length > 0);

            };

            self.untrack = function(row){
                List.remove(invalidCellsByRow, function(item){
                    return item.row === row;
                });

                List.remove(dirtyCellsByRow, function(item){
                    return item.row === row;
                });

                setInvalid(invalidCellsByRow.length > 0);
            };

        }
    };

}]);

lgTable.directive('trackTableRow', function(){

    return {
        restrict:'A',
        priority:-1,
        require:['^trackTable', 'ngForm'],
        controller: function($scope, $parse, $attrs, $element){
            var self = this;
            var row = $parse($attrs.trackTableRow)($scope);
            self.rowFormCtrl = $element.controller('form');
            var trackTableCtrl = $element.controller('trackTable');

            self.isCellDirty = function(cell){
                return trackTableCtrl.isCellDirty(row, cell);
            };

            self.setCellDirty = function(cell, isDirty){
                trackTableCtrl.setCellDirty(row, cell, isDirty);
            };

            self.setCellInvalid = function(cell, isInvalid){
                trackTableCtrl.setCellInvalid(row, cell, isInvalid);
            };

        }
    };

});

lgTable.directive('trackTableCell', function(){
    return {
        restrict:'A',
        priority:-1,
        scope:true,
        require:['^trackTableRow', 'ngForm'],
        controller: function($scope, $attrs, $element){

            var cellFormCtrl = $element.controller('form');
            var cellName = cellFormCtrl.$name;
            var trackTableRowCtrl = $element.controller('trackTableRow');


            if(trackTableRowCtrl.isCellDirty(cellName)){
                cellFormCtrl.$setDirty();
            } else {
                cellFormCtrl.$setPristine();
            }

            $scope.$watch(function(){
                return cellFormCtrl.$dirty;
            }, function(newValue, oldValue){
                if(newValue === oldValue) {
                    return;
                }

                trackTableRowCtrl.setCellDirty(cellName, newValue);

            });


            $scope.$watch(function(){
                return cellFormCtrl.$invalid;
            }, function(newValue, oldValue){
                if(newValue === oldValue) {
                    return;
                }

                trackTableRowCtrl.setCellInvalid(cellName, newValue);

            });

        }
    };

});
